int goingOnBreak;
int THEATER_TESTS;



/*
Condition *startMovieConditionVariable;
Condition *managerClerkGoingOnBreakConditionVariable;
Lock *managerLock;
*/
int startMovieConditionVariable;
int managerClerkGoingOnBreakConditionVariable;
int managerLock;
int ticketsTaken;
/*int takingTicketsLock;*/
int runBreak;

void Manager()
{
	int i,j;
	int totalEarnings;
	int totalTicketEarnings;
	int totalFoodEarnings;
	int announceEarningsCounter = 0;

	 /*Set runBreak to 1 to see manager tell ticketTaker to go on break*/
	runBreak = 0;
	
	/*waits movie theater so that everything will only start when their data has been initialized*/
	/*LockAcquire(initialLock);
	LockRelease(initialLock);*/

	if(THEATER_TESTS == 2) {
		announceEarningsCounter = 99999;
	}
	
	while (1)
	{

				Yield();
		
		/*for(i=0;i<5000;i++)
		{
			printf("Number of Customer %i\n",numberOfCustomers);
			currentThread->Yield();
		}*/
		/*  */
		
			
		/*print out earnings*/
		if(announceEarningsCounter >= 50000) {
			totalEarnings = 0;
			totalTicketEarnings = 0;
			totalFoodEarnings = 0;

			for(i = 0; i < ticketClerks; i++) {
				/*
				ticketClerkLocks[i]->Acquire();
				*/
				LockAcquire(ticketClerkLocks[i]);
				totalEarnings += ticketEarnings[i];
				totalTicketEarnings += ticketEarnings[i];
				Write1("Manager collected %i",20,1,ticketEarnings[i]);
				Write1("From TicketClerk %i\n", 19 , 1, i);
				/*printf("Manager collected %i from TicketClerk %i\n", ticketEarnings[i], i);*/
				/*
				ticketClerkLocks[i]->Release();
				*/
				LockRelease(ticketClerkLocks[i]);
			}
			for(i = 0; i < foodClerks; i++) {
				/*
				foodClerkLocks[i]->Acquire();
				*/
				LockAcquire(foodClerkLocks[i]);
				totalEarnings += foodEarnings[i];
				totalFoodEarnings += foodEarnings[i];
				Write1("Manager collected %i",20,1,foodEarnings[i]);
				Write1("From FoodClerk %i\n", 19 , 1, i);
				/*printf("Manager collected %i from FoodClerk %i\n", foodEarnings[i], i);*/
				/*
				foodClerkLocks[i]->Release();
				*/
				LockRelease(foodClerkLocks[i]);
			}
			Write1("Total money made by office = %i\n", 33, 1, totalEarnings);
			/*printf("Total money made by office = %i\n", totalEarnings);*/

			if(THEATER_TESTS == 2) {
				Exit(0);
			}
			announceEarningsCounter = 0;

		}
		else {
			announceEarningsCounter++;
		}
		
		if(numberOfCustomers==0) /* */
		{
			Write("Theater is done\n",17,1);
			Exit(0);
		}
			
		LockAcquire(takingTicketsLock);
		if(movieStarted==0&&ticketsTaken<=0&&takingTickets==0)
		{	
			
			Broadcast(lobbyCV,takingTicketsLock);
			takingTickets=1;
			
		}
		LockRelease(takingTicketsLock);
		
		/*GWrite1("Customs Seathed = %I\n", 22 , 1,custsSeated);
		Write1("Tickets Taken = %i\n", 20 , 1,ticketsTaken);
		Write1("Movie Started = %i\n", 20 , 1,movieStarted);
		Write1("Taking Tickets = %i\n", 21 , 1,takingTickets);
		Write1("Customs Remaining = %i\n", 24 , 1,numberOfCustomers);
		Write1("Customs Served = %i\n", 21 , 1,customersServed);*/


	/*	printf("Custs Seated = %i\n\nTickets Taken = %i\n\n Movie Started = %i\n\n Taking Tickets = %i\n\nCustomers Remaining = %i \n\n Customers Served = %i\n\n",custsSeated,ticketsTaken,movieStarted,takingTickets,numberOfCustomers,customersServed);*/
		
		/*if(movieStarted=1&&techThreads->getStatus()==BLOCKED)
		{
			techManagerVariable->Signal(techLock);
		}*/

		/* Randomly starts the movie */
	
		if(takingTickets&&ticketsTaken>0)
		{
			
			int startMovieRandom;
			startMovieRandom = 0; /*Generate a random number to randomly start a movie*/
			if (startMovieRandom <1)
			{
				
				Write("Manager is telling the MovieTechnician to start the movie.\n",60,1);
				/*
				managerLock->Acquire();
				takingTicketsLock->Acquire();
				*/
				LockAcquire(managerLock);
				LockAcquire(takingTicketsLock);
				LockAcquire(techLock);
					movieStarted = 1;
					takingTickets=0;
					/*
					techManagerVariable->Signal(techLock);
					*/
					Signal(techManagerVariable, techLock);

				/*	
				takingTicketsLock->Release();
				managerLock->Release();
				*/
				LockRelease(techLock);
				LockRelease(takingTicketsLock);
				LockRelease(managerLock);
			}
		}
		/* If the employee lines are empty, then there is a 20% chance that the employee will go on break */
		if (runBreak == 1)
		{
		/*
		ticketClerkLineLock->Acquire();
		*/
		LockAcquire(ticketClerkLineLock);
		for (i=0; i < ticketClerks; i++)
		{

			/*
			ticketClerkLocks[i]->Acquire();
			*/
			LockAcquire(ticketClerkLocks[i]);
			
			if (ticketClerkLineCount[i] == 0 && ticketClerkState[i]!=no_clerk && ticketClerkState[i]!=on_break && ticketClerkState[i]!=go_on_break) /*This will look for when there a clerk that isn't on break */
			{

				goingOnBreak = rand() %10 + 1; /* Generates a random number used for determining whether the clerk is to go on break */
				if( goingOnBreak < 3) /* There is a 20% chance that the clerk will go on break */
				{

					for(j = 0; j<ticketClerks;j++)
					{

						if(i!=j) /*  */
						{

							/* Put the ticketClerk[i] that has zero customers in line on break */
							LockAcquire(ticketClerkLocks[j]);
							/*
							ticketClerkLocks[j]->Acquire();
							*/
							if (ticketClerkState[j]!=on_break && ticketClerkState[j]!=no_clerk && ticketClerkState[j]!=go_on_break) /* 20% chance that the ticketClerk will go on break */
							{

							
								if (ticketClerkState[i]==available)
								{

									ticketClerkState[i] = on_break;
									/*
									ticketClerkConditionVariables[i]->Signal(ticketClerkLocks[i]); //Telling the clerk to go on break
									*/
									Signal(ticketClerkConditionVariables[i],ticketClerkLocks[i]);

								}
								else
								{

									ticketClerkState[i] = go_on_break;

								}
								/*Write("Manager has told TicketClerk %d to go on break.\n", i);*/

								/*
								ticketClerkLocks[j]->Release();
								*/
								LockRelease(ticketClerkLocks[j]);
								


								break;

							}
							/*
							ticketClerkLocks[j]->Release();
							*/
							
							LockRelease(ticketClerkLocks[j]);


						}

					}


				}

				


			}
			/*
			ticketClerkLocks[i]->Release();
			*/
			LockRelease(ticketClerkLocks[i]);


		}
		/*
		ticketClerkLineLock->Release();
		*/
		LockRelease(ticketClerkLineLock);

	}
		
		 /*for(i=0;i<foodClerks;i++)
		 {

			 foodClerkLocks[i]->Acquire();
			 foodClerkLineLock->Acquire();
			 if (foodClerkLineCount[i] == 0 && foodClerkStates[i]!=no_clerk && foodClerkStates[i]!=on_break)
			 {
				 // Put the foodClerk[i] that has zero customers in line on break 
				 goingOnBreak = rand() %10 + 1;
				 if (goingOnBreak < 3) // 20% chance that the foodClerk will go on break 
				 {
					 for(j = 0; j<foodClerks;j++)
					 {
						 goingOnBreak = rand() %10 + 1;
						 if(i!=j)
						 {
							 // Put the ticketClerk[i] that has zero customers in line on break 
							 foodClerkLocks[j]->Acquire();
							 if ((foodClerkStates[j]!=on_break)&&(foodClerkStates[j]!=no_clerk) &&goingOnBreak < 3) // 20% chance that the ticketClerk will go on break 
							 {

								 if (foodClerkStates[i]==available)
								 {
									 foodClerkStates[i] = on_break;
									 foodClerkConditionVariables[i]->Signal(foodClerkLocks[i]);
								 }
								 else
								 {
									 foodClerkStates[i] = go_on_break;
								 }
								
								 printf("Manager has told ConcessionClerk %d to go on break.\n", i);
								 foodClerkLocks[j]->Release();

								 break;
							 }
							 foodClerkLocks[j]->Release();
						 }
					 }


				 }
			 }
			 foodClerkLocks[i]->Release();
			 foodClerkLineLock->Release();
		 }
		 for (i=0; i < ticketTakers; i++)
		 {
			 ticketTakerLineLock->Acquire();

			 ticketTakerLocks[i]->Acquire();
			 if ((ticketTakerLineCount[i] == 0)&& ticketTakerStates[i]!=no_clerk && ticketTakerStates[i]!=on_break)
			 {
				 goingOnBreak = rand() % 10 + 1;
					 if(goingOnBreak < 3)
					 {
						 for(j = 0; j<ticketTakers;j++)
						 {
							 if(i!=j)
							 {
								 // Put the ticketClerk[i] that has zero customers in line on break 
								 ticketTakerLocks[j]->Acquire();
								 if ((ticketTakerStates[j]!=on_break)&&(ticketTakerStates[j]!=no_clerk)) // 20% chance that the ticketClerk will go on break 
								 {

									 if (ticketTakerStates[i]==available)
									 {
										 ticketTakerStates[i] = on_break;
										 ticketTakerConditionVariables[i]->Signal(ticketTakerLocks[i]);
									 }
									 else
									 {
										 ticketTakerStates[i] = go_on_break;
									 }
									 printf("Manager has told TicketTaker %d to go on break.\n", i);
									 ticketTakerLocks[j]->Release();

									 break;
								 }
								 ticketTakerLocks[j]->Release();
							 }
						 }
					 }
				 // Put the ticketTaker[i] that has zero customers in line on break 
				 // 20% chance that the ticketTaker will go on break 


			 }
			 ticketTakerLocks[i]->Release();
			 ticketTakerLineLock->Release();
		 }*/
		/*===============================================================================*/
		
		/*Checks if the ticketClerk have less than 3 employees and there is another person working*/
		/*If they do, then they have 20% of going on break*/
		 /*for (i=0; i < ticketClerks; i++)
		 {
			 ticketClerkLocks[i]->Acquire();
			 ticketClerkLineLock->Acquire();
			 if ((ticketClerkLineCount[i] < 3)&&(ticketClerkState[i]!=on_break)) // find a clerk that has less than 3 employees and isn't on break 
			 {
				
					 for (j = 0; j < ticketClerks; j++)
					 {
						 if (j!=i) // Find another clerk that isn't the same as the first clerk 
						 {
							 ticketClerkLocks[j]->Acquire();
							 if ((ticketClerkState[j]!=on_break)&&(ticketClerkState[j]!=no_clerk)) // Check whether the second clerk is working. 
							 {
									 if (ticketClerkState[i]==available)
									 {
										 ticketClerkState[i] = on_break;
										 ticketClerkConditionVariables[i]->Signal(ticketClerkLocks[i]);
									 }
									 else
									 {
									 ticketClerkState[i] = go_on_break; // If there is a second clerk working then the first clerk can go on break 
									 }
									 printf("Manager has told TicketClerk %d to go on break.\n", i);

									 ticketClerkLineConditionVariables[i]->Broadcast(ticketClerkLineLock); // Tells all the customer in line of the first clerk that he is going on break
									 ticketClerkLocks[j]->Release();
									 break;																	// They will all need to find a new line. Broadcasts to all ticketClerks 
									
							 }
							 ticketClerkLocks[j]->Release();
						 }
					 }
			 }
						 ticketClerkLineLock->Release();
						 ticketClerkLocks[i]->Release();
		 }
		
		 for (i=0; i < foodClerks; i++)
		 {
			 foodClerkLineLock->Acquire();
			 foodClerkLocks[i]->Acquire();
			 if ((foodClerkLineCount[i] < 3)&&(foodClerkStates[i]!=on_break))
			 {
				 goingOnBreak = rand() % 10 + 1;
				 if(goingOnBreak < 3)
				 {
					 for (j = 0; j < foodClerks; j++)
					 {
						 if (j!=i)
						 {
							 foodClerkLocks[j]->Acquire();
							 if ((foodClerkStates[j]!=on_break)&&(foodClerkStates[j]!=no_clerk))
							 {
									 if (foodClerkStates[i]==available)
									 {
										 foodClerkStates[i] = on_break;

										 foodClerkConditionVariables[i]->Signal(foodClerkLocks[i]);
									 }
									 else
									 {
									 foodClerkStates[i] = go_on_break;
									 }
									 printf("Manager has told ConcessionClerk %d to go on break.\n", i);

									 foodClerkLineConditionVariables[i]->Broadcast(foodClerkLineLock);
									 foodClerkLocks[j]->Release();
									 break;
							 }
							 foodClerkLocks[j]->Release();
						 }
					 }
				 }
			 }
			 foodClerkLineLock->Release();
			 foodClerkLocks[i]->Release();
		 }
		 for (i=0; i < ticketTakers; i++)
		 {
			 ticketTakerLineLock->Acquire();
			 ticketTakerLocks[i]->Acquire();
			 if ((ticketTakerLineCount[i] < 3)&&(ticketTakerStates[i]!=on_break))
			 {
				 goingOnBreak = rand() % 10 + 1;
				 if(goingOnBreak < 3)
				 {
					 for (j = 0; j < ticketTakers; j++)
					 {
						 if (j!=i)
						 {
							 ticketTakerLocks[j]->Acquire();
							 if ((ticketTakerStates[j]!=on_break)&&(ticketTakerStates[j]!=no_clerk))
							 {
									 if (ticketTakerStates[i]==available)
									 {
										 ticketTakerStates[i] = on_break;

										 ticketTakerConditionVariables[i]->Signal(ticketTakerLocks[i]);
									 }
									 else
									 {
									 ticketTakerStates[i] = go_on_break;
									 }
									 printf("Manager has told TicketTaker %d to go on break.\n", i);

									 ticketTakerLineConditionVariables[i]->Broadcast(ticketTakerLineLock);
									 ticketTakerLocks[j]->Release();
									 break;
							 }
							 ticketTakerLocks[j]->Release();
						 }
					 }
				 }
			 }
			 ticketTakerLineLock->Release();
			 ticketTakerLocks[i]->Release();
		 }*/
		/*============================================================================================*/
		/*If an employee has a line thats greater than 5, then an employee of the same type will get off break*/
		
		/* for (i=0; i<ticketClerks; i++)
		 {
			 ticketClerkLineLock->Acquire();
			 if (ticketClerkLineCount[i] > 5) // Looks for a clerk that has a line of more than 5 people
			 {
				 for (j=0; j<ticketClerks; j++) // Looks for a second clerk that is on break
				 {
					 if (j!=i) // Makes sure that the first clerk isn't equal to the second clerk
					 {
						 ticketClerkLocks[j]->Acquire();
						 if (ticketClerkState[j]==on_break)
						 {
							 ticketClerkState[j]=available; // The clerk goes off break and gets back to work
							 ticketClerkConditionVariables[j]->Signal(ticketClerkLocks[j]);
							 ticketClerkLineConditionVariables[i]->Broadcast(ticketClerkLineLock); // Broadcasts to everyone in the line of the first clerk that there is a new line available 
														 for (int k = 0; k < 10;k++)
								 {
															 printf("Manager has told TicketClerk %d to get off break.\n", i);

								 }
							 ticketClerkLocks[j]->Release();


							 break;
						 }
						 ticketClerkLocks[j]->Release();
					 }
				 }
			 }
			 ticketClerkLineLock->Release();
		 }
		
		

		 for (i=0; i<foodClerks; i++)
		 {
			 foodClerkLineLock->Acquire();
			 if (foodClerkLineCount[i] > 5)
			 {
				 for (j=0; j<foodClerks; j++)
				 {
					 if (j!=i)
					 {
						 foodClerkLocks[j]->Acquire();
						 if (foodClerkStates[j]==on_break)
						 {
							 foodClerkStates[j]=available;
							 foodClerkConditionVariables[j]->Signal(foodClerkLocks[j]);
							 foodClerkLineConditionVariables[i]->Broadcast(foodClerkLineLock);
							 foodClerkLocks[j]->Release();
							 break;
						 }
						 foodClerkLocks[j]->Release();
					 }
				 }
			 }
			 foodClerkLineLock->Release();
		 }
		
				
		 for (i=0; i<ticketTakers; i++)
		 {
			 ticketTakerLineLock->Acquire();
			 if (ticketTakerLineCount[i] > 5)
			 {
				 for (j=0; j<ticketTakers; j++)
				 {
					 if (j!=i)
					 {
						 ticketTakerLocks[j]->Acquire();
						 if (ticketTakerStates[j]==on_break)
						 {
							 ticketTakerStates[j]=available;		
							 ticketTakerConditionVariables[j]->Signal(ticketTakerLocks[j]);
							 ticketTakerLineConditionVariables[i]->Broadcast(ticketTakerLineLock);
							 ticketTakerLocks[j]->Release();
							 break;
						 }
						 ticketTakerLocks[j]->Release();
					 }
				 }
			 }
			 ticketTakerLineLock->Release();
			

		 }*/
		


		/*//ticketClerkLineLock->Release();			
		//foodClerkLineLock->Release();
		//ticketTakerLineLock->Release();*/
	
		if(THEATER_TESTS == 1)
			break;
		


	} /* While 1 */
}
